package processing.test.mechaapp;
//game;

import processing.core.*;

public abstract class Atom {
	public static PApplet applet;
	public static float size = 25;//Easily change the size of the atoms if needed
	public float xChord;//X chord for the grid
	public float yChord;//Y chord for the grid
	public int points; //Value each atom is worth
	public int ith;//The atom "knows" where it is in the grid array
	public int jth;//Helpful for debugging
	public Atom bonds[];//Array for bond linking
	public Atom doublebonds[];//Array for double bonds links
	public boolean isVisited, loopChecked = false;
	public boolean highlight;
	public int numBonds;//The current number of bonds the atom has 
	public int maxBonds;//The total number of bonds the atom can have
	public Molecule molecule;
	
	abstract public void drawMe();
	
	//Method that draws the lines to create the bonding of atoms.
	public void drawLines(){
		if(this instanceof blankAtom) return;
		applet.stroke(255);//white line
		for(int i=0; i<bonds.length; i++){
			if(bonds[i] != null)
				applet.line(xChord, yChord, bonds[i].xChord, bonds[i].yChord);
		}
		//strokeWeight() is the width of the line's stroke 
		applet.strokeWeight(4);//Double bond 
		for(int i = 0; i<doublebonds.length; i++){
			if(doublebonds[i]!=null){
				applet.line(xChord,yChord,doublebonds[i].xChord,doublebonds[i].yChord);
			}
			
		}
		applet.strokeWeight(1);//Single bond
	}
	
	//This method makes a bond to the atom passed into it, then returns a reference to the
	//old molecule that this atom was apart of.
	//That way the main class knows to delete the old molecule.
	public Molecule makeBond(Atom atom) {
		//since blankAtom does not have an array called bonds, we need to skip this method in order
		//to avoid a nullPointerException!
		if(numBonds == maxBonds || atom.numBonds == atom.maxBonds || atom instanceof blankAtom) return molecule;
		for(int i=0; i<doublebonds.length; i++)
			if(doublebonds[i] == atom)
				return molecule;
		
		//check for ability to double bond before single bond
		//This changes the game dynamic 
		if((maxBonds - numBonds) >= 2 && (atom.maxBonds - atom.numBonds) >= 2){
			
			//add atom to doublebond array
			for(int i=0; i<doublebonds.length; i++){
				if(doublebonds[i] == null){
					doublebonds[i] = atom;
					break;
				}
			}
			
			//also sets this atom to the atom's array of bonds
			for(int i=0; i<atom.doublebonds.length; i++){
				if(atom.doublebonds[i] == null){
					atom.doublebonds[i] = this;
					break;
				}
			}
			//save a reference to the old molecule of atom
			Molecule tempMolecule = this.molecule;
			//bond this atom to the other atom's molecule	
			atom.molecule.bondToMolecule(this);
			
			numBonds+=2;
			atom.numBonds+=2;
			
			//debugging
			//System.out.println(molecule.toString());
			//System.out.println("Is Complete? "+molecule.checkCompleteness());
			
			return tempMolecule;
			
		}
		
		else 
		//adds that atom to this array of bonds
		for(int i=0; i<bonds.length; i++){
			if(bonds[i] == null){
				bonds[i] = atom;
				break;
			}
		}
		
		//also sets this atom to the atom's array of bonds
		for(int i=0; i<atom.bonds.length; i++){
			if(atom.bonds[i] == null){
				atom.bonds[i] = this;
				break;
			}
		}
		
		//save a reference to the old molecule of atom
		Molecule tempMolecule = this.molecule;
		//bond this atom to the other atom's molecule	
		atom.molecule.bondToMolecule(this);
		
		numBonds++;
		atom.numBonds++;
		
		//debugging
		//System.out.println(molecule.toString());
		//System.out.println("Is Complete? "+molecule.checkCompleteness());
		
		return tempMolecule;
	}
	
	//returns a reference to the newly created molecule
	//or returns null if nothing is changed.
	public Molecule breakBond(Atom atom){
		if(numBonds == 0 || atom instanceof blankAtom) return null;
		
		boolean isBondedWith = false;
		Molecule tempMolecule = null;
		int BondsRemoved = 1;
		
		for(int i=0; i<bonds.length; i++){
			if(bonds[i] == atom){
				//this atom must remove its self from its own molecule
				//note: an atom has to break from the molecule before it removes
				//atoms from its bond array
				tempMolecule = molecule.breakFromMolecule(this, atom);
				//removes the atom from its bond
				bonds[i] = null;
				isBondedWith = true;
				break;
			}
		}
		for(int i=0; i<doublebonds.length;i++){
			if(doublebonds[i] == atom){
				tempMolecule = molecule.breakFromMolecule(this, atom);
				//removes the atom from its bond
				doublebonds[i] = null;
				isBondedWith = true;
				BondsRemoved = 2;
				break;	
			}
		}
		
		if(!isBondedWith) return null;//if the atom is not bonded to this current atom, then return.
		
		//removes itself from the other atoms bonds
		for(int i=0; i<atom.bonds.length; i++){
			if(atom.bonds[i] == this){
				atom.bonds[i] = null;
				break;
			}
		}
		for(int i=0; i<atom.doublebonds.length; i++){
			if(atom.doublebonds[i] == this){
				atom.doublebonds[i] = null;
				break;
			}
		}
		
		numBonds-=BondsRemoved;
		atom.numBonds-=BondsRemoved;
		
		//debugging
		//System.out.println(molecule.toString());
		
		return tempMolecule;
	}
	
	//needed to set the attributes of the current applet.
	public static void setApplet(PApplet frame){
		applet = frame;
	}
	
	public String toString(){
		return "I am an Atom"+
				"\nith = "+ith+" jth = "+jth;
	}
	
}
